package com.scs.application.modules.base.service.impl;

import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.collect.Lists;
import com.scs.application.consts.GlobalConsts;
import com.scs.application.consts.SerialKeys;
import com.scs.application.core.consts.ErrorCode;
import com.scs.application.core.exception.BusinessException;
import com.scs.application.core.query.QueryContext;
import com.scs.application.core.service.BaseServiceImpl;
import com.scs.application.core.utils.*;
import com.scs.application.modules.base.dto.*;
import com.scs.application.modules.base.entity.*;
import com.scs.application.modules.base.enums.ExcelImportBaseDataConfig;
import com.scs.application.modules.base.mapper.*;
import com.scs.application.modules.base.service.*;
import com.scs.application.modules.base.util.CommonService;
import com.scs.application.modules.cfg.entity.Parameter;
import com.scs.application.modules.cfg.mapper.ParameterMapper;
import com.scs.application.modules.cfg.utils.ParameterUtils;
import com.scs.application.modules.dept.entity.LimitMatr;
import com.scs.application.modules.dept.mapper.LimitMatrMapper;
import com.scs.application.modules.price.dto.AdjustBuildScpDTO;
import com.scs.application.modules.price.dto.AdjustStockDTO;
import com.scs.application.modules.price.service.AdjustmentService;
import com.scs.application.modules.project.Const;
import com.scs.application.modules.sys.entity.Log;
import com.scs.application.modules.sys.enums.BusType;
import com.scs.application.modules.sys.enums.LogType;
import com.scs.application.modules.sys.model.RestResult;
import com.scs.application.modules.sys.service.LogService;
import com.scs.application.modules.sys.service.ScheduleJobService;
import com.scs.application.modules.sys.service.impl.SystemCommonServiceImpl;
import com.scs.application.modules.thirdparty.dto.MatrDTO;
import com.scs.application.modules.thirdparty.service.MscmService;
import com.scs.application.modules.wm.dto.DeliveryDTO;
import com.scs.application.modules.wm.entity.Stock;
import com.scs.application.modules.wm.entity.StockLock;
import com.scs.application.modules.wm.service.StockLockService;
import com.scs.application.modules.wm.service.StockService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Lazy;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 耗材信息 服务实现类
 * </p>
 */
@Slf4j
@Service
public class MatrServiceImpl extends BaseServiceImpl<MatrMapper, Matr> implements MatrService {

    @Autowired
    private MscmService mscmService;

    @Autowired
    private SupplierMapper supplierMapper;

    @Autowired
    private SupplierService supplierService;

    @Value("${res.real-path}")
    private String resPath;

    @Autowired
    private MatrUnitMapper matrUnitMapper;

    @Autowired
    private MatrUnitService matrUnitService;

    @Autowired
    private MfgMapper mfgMapper;

    @Autowired
    private MfgService mfgService;
    @Autowired
    private MatrCategoryMapper matrCategoryMapper;
    @Autowired
    private MatrCategoryService matrCategoryService;

    @Autowired
    private LimitMatrMapper limitMatrMapper;

    @Autowired
    private LogService logService;


    @Autowired
    private StockService stockService;

    @Autowired
    private StockLockService stockLockService;

    @Autowired
    private PackTempletItemService packTempletItemService;


    @Autowired
    private PackTempletMapper packTempletMapper;

    @Autowired
    @Lazy
    private ScheduleJobService scheduleJobService;

    @Autowired
    private ParameterMapper parameterMapper;

    @Autowired
    private AdjustmentService adjustmentService;

    @Autowired
    @Lazy
    private SystemCommonServiceImpl systemCommonService;


    @Override
    public List<Map> listWithStock(QueryContext queryContext) {
        String deptId = (String) queryContext.getParams().get("deptId");
        int limitCount = limitMatrMapper.selectCount(new QueryWrapper<LimitMatr>()
                .eq("dept_id", deptId)
                .eq("is_apply", GlobalConsts.YES));
        return this.baseMapper.listWithStock(queryContext.getWrapper(), queryContext.getParams(), limitCount);
    }


    @Override
    @Transactional
    public boolean saveOrUpdate(Matr entity) {
        if (StringUtils.isBlank(entity.getMfgId())) {
            entity.setMfgId(null);
        }
        entity.setNamePy(PinYinUtils.getAlpha(entity.getName()));
// 耗材禁用后操作
        if ((entity.getFlagDisabled() != null && entity.getFlagDisabled())
                || (entity.getHisDisabled() != null && entity.getHisDisabled())
                || (entity.getMscmDisabled() != null && entity.getMscmDisabled())
                || (entity.getHrpDisabled() != null && entity.getHrpDisabled())
                || (entity.getHrpFinanceDisabled() != null && entity.getHrpFinanceDisabled())) {
            List<String> idList = Collections.singletonList(entity.getId());
            this.matrDisableAfter(idList);
        }

        if (entity.isNewRecord()) {
            entity.setId(IdWorker.getIdStr());
            if (StringUtils.isBlank(entity.getHrpCode())) {
                entity.setHrpCode(entity.getId());
            }
        }

        //编辑时进行各种校验
        Boolean success = super.saveOrUpdate(entity);
        if (StringUtils.isNotBlank(entity.getSkuUnit()) && entity.getSkuPrice() != null) {
            MatrUnit matrUnit = matrUnitService.getOne(Wrappers.<MatrUnit>query().eq("flag_base", true).eq("matr_id", entity.id));
            if (matrUnit == null) {
                matrUnit = new MatrUnit();
                matrUnit.setRate(1.0).setFlagBase(true)
                        .setFlagPurchase(true).setFlagApply(true)
                        .setFlagDisabled(false).setMatrId(entity.id)
                        .setUnit(entity.getSkuUnit())
                        .setPrice(entity.getSkuPrice());
                matrUnitService.saveOrUpdate(matrUnit);
            } else if (!matrUnit.getUnit().equals(entity.getSkuUnit()) || matrUnit.getPrice().compareTo(entity.getSkuPrice()) != 0) {
                matrUnit.setUnit(entity.getSkuUnit())
                        .setPrice(entity.getSkuPrice());
                matrUnitService.saveOrUpdate(matrUnit);
            }
        }




        return success;
    }

    private void matrDisableAfter(List<String> matrIds) {
        List<PackTempletItem> packTempletItems = packTempletItemService.list(Wrappers.<PackTempletItem>query().in("matr_id", matrIds));
        if (packTempletItems == null || packTempletItems.isEmpty()) return;
        List<String> packTempletItemIds = packTempletItems.stream()
                .map(PackTempletItem::getId).distinct().collect(Collectors.toList());
        List<String> packTempletIds = packTempletItems.stream()
                .map(PackTempletItem::getPackTempletId).distinct().collect(Collectors.toList());
        packTempletItemService.removeCascadeByIds(packTempletItemIds);
        packTempletMapper.calculatePackAmount(packTempletIds);
    }

    /**
     * @Description： 根据编辑配置进行更新
     */
    public void updateStock(Matr entity) {
        if (StringUtils.isBlank(entity.getId())) return;
        List<MatrEditConfigDTO> matrEditConfigDTOList = ParameterUtils.matrEditConfigList();
        if (matrEditConfigDTOList == null) { //没有配置时，使用默认校验
            if (!"1".equals(entity.getIsEdit()) && StringUtils.isNotBlank(entity.getId()) && stockService.count(Wrappers.<Stock>query().eq("matr_id", entity.getId())) > 0) {
                throw new BusinessException("该耗材已有库存记录，不允许修改");
            }
        }
        ;
        Matr matrDb = this.getById(entity.getId());
        JSONObject matrJsonPage = JSONObject.parseObject(JSON.toJSONString(entity));
        JSONObject matrJsonDb = JSONObject.parseObject(JSON.toJSONString(matrDb));
        UpdateWrapper updateWrapper = null;
        boolean updateStock = false;

        //判断耗材是否编辑
        for (MatrEditConfigDTO matrEditConfigDTO : matrEditConfigDTOList) {
            String key = matrEditConfigDTO.getPkname();
            //不可编辑
            if (!"1".equals(matrEditConfigDTO.getFlagEnabled()) && !matrJsonPage.getString(key).equals(matrJsonDb.getString(key))) {
                throw new BusinessException("系统配置，字段【%s】当前不可编辑", matrEditConfigDTO.getPkText());
            }

            //需要更新库存的字段
            if ("1".equals(matrEditConfigDTO.getFlagUpdateStock()) && !matrJsonPage.getString(key).equals(matrJsonDb.getString(key))) {
                if (updateWrapper == null) updateWrapper = Wrappers.<StockLock>update();
                updateWrapper.set(StringUtils.camelToUnderline(key, 2), matrJsonPage.getString(key));

                //供应商 名称和id一起更新
                if (key.equals("supplierName")) {
                    updateWrapper.set("supplier_id", entity.getSupplierId());
                }
                //厂商 名称和id一起更新
                if (key.equals("mfgName")) {
                    updateWrapper.set("mfg_id", entity.getMfgId());
                }
                updateStock = true;
            }
        }
        if (updateWrapper != null) {
            //该耗材的所有相关未锁定的库存数量大于0的库存
            updateWrapper.eq("matr_id", entity.getId());
            updateWrapper.ne("sku_qty", 0);
            List<StockLock> stockLockList = stockLockService.list(Wrappers.<StockLock>query().select("stock_id").eq("matr_id", entity.getId()));
            if (stockLockList != null && stockLockList.size() > 0) updateWrapper.notIn("id", stockLockList);
            stockService.update(updateWrapper);
        } else { //没有配置库存更新时时，使用默认校验
            if (!"1".equals(entity.getIsEdit()) && StringUtils.isNotBlank(entity.getId()) && stockService.count(Wrappers.<Stock>query().eq("matr_id", entity.getId())) > 0) {
                throw new BusinessException("该耗材已有库存记录，不允许修改");
            }
        }
    }

    private void logDebug(Matr matr,String field,Object valueOld,Object valueNew) {
        log.info(" 商品同步数据变更 his编码 {} 变更字段 {} 旧值{} 新值{}  ",matr.getHisCode(),field,valueOld, valueNew);
    }

    // 属性是否发生变化
    private Boolean hasChange(Matr matr,MatrDTO dto,Supplier supplier) {
        if (!StringUtils.equalsNoSpec(matr.getSupplierName(), supplier.getName()))  {
            logDebug(matr,"10SupplierName",matr.getSupplierName(),supplier.getName());
            return true;
        }
        //StringUtils.isBlank(dto.getMaterialTradeName()) ? dto.getName() : dto.getMaterialTradeName()
        if (!StringUtils.equalsNoSpec(matr.getName(), StringUtils.isBlank(dto.getMaterialTradeName()) ? dto.getName() : dto.getMaterialTradeName()))  {
            logDebug(matr,"11name",matr.getName(),StringUtils.isBlank(dto.getMaterialTradeName()) ? dto.getName() : dto.getMaterialTradeName());
            return true;
        }
        if (!StringUtils.equalsNoSpec(matr.getSpec(), dto.getSpec()))  {
            logDebug(matr,"11spec",matr.getSpec(),dto.getSpec());
            return true;
        }
        if (!StringUtils.equalsNoSpec(matr.getMfgName(), dto.getMfgName()))  {
            logDebug(matr,"11MfgName",matr.getMfgName(),dto.getMfgName());
            return true;
        }
        if (!StringUtils.equalsNoSpec(matr.getMfgName(), dto.getMfgName()))  {
            logDebug(matr,"11MfgName",matr.getMfgName(),dto.getMfgName());
            return true;
        }
        if (!ObjectUtil.equal(StringUtils.toBoolean(matr.getMscmDisabled(),false), !dto.getInactive()))  {
            logDebug(matr,"12MscmDisabled",matr.getMscmDisabled(),StringUtils.toBoolean(!dto.getInactive(),false));
            return false;
        }
        if (!ObjectUtil.equal(StringUtils.toBoolean(matr.getFlagConsignment(),false), dto.getIsConsignment()))  {
            logDebug(matr,"12FlagConsignment",matr.getFlagConsignment(),StringUtils.toBoolean(dto.getIsConsignment(),false));
            return false;
        }
        if (!ObjectUtil.equal(StringUtils.toBoolean(matr.getFlagOmoc(),false), dto.getIsOmoc()))  {
            logDebug(matr,"12FlagOmoc",matr.getFlagOmoc(),StringUtils.toBoolean(dto.getIsOmoc(),false));
            return false;
        }
        if (!StringUtils.equalsNoSpec(matr.getSkuUnit(), dto.getSkuUnit()))  {
            logDebug(matr,"12SkuUnit",matr.getSkuUnit(),dto.getSkuUnit());
            return false;
        }
        if (!StringUtils.equalsNoSpec(matr.getCertificateNo(), dto.getCertificateNo()))  {
            logDebug(matr,"12CertificateNo",matr.getCertificateNo(),dto.getCertificateNo());
            return false;
        }
        if (!StringUtils.equalsNoSpec(matr.getHrpCode(), dto.getMaterialHrpCode()))  {
            logDebug(matr,"12HrpCode",matr.getHrpCode(),dto.getMaterialHrpCode());
            return false;
        }
        return  false;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public String syncMatrsFromMscm() {

        // 获取MSCM系统中耗材数据
        List<MatrDTO> dtos = mscmService.getMatrList();
        log.info("供应商系统同步耗材，数量{}", dtos.size());
        if (dtos.isEmpty()) {
            return StrUtil.format("供应商系统同步耗材,没有获取到耗材");
        }

        List<Supplier> suppliers = supplierMapper.selectList(
                Wrappers.<Supplier>query().select("id,name,mscm_code").isNotNull("mscm_code")
        );
        Map<String, Supplier> supplierMap = suppliers.stream().collect(Collectors.toMap(o -> o.getMscmCode(), o -> o, (o1, o2) -> o1));

        List<Matr> matrs = this.list(Wrappers.<Matr>query()
                .isNotNull("mscm_code"));
        Map<String, Matr> matrMap = matrs.stream()
                .filter(o -> StringUtils.isNotBlank(o.getMscmCode()))
                .collect(Collectors.toMap(o -> o.getMscmCode(), o -> o, (o1, o2) -> o1));


        List<Matr> saveOrUpdateMatrs = Lists.newArrayList();
        List<AdjustBuildScpDTO> adjustBuildList = Lists.newArrayList();
        AdjustBuildScpDTO adjustBuild;
        int numAdd = 0,numUpdate= 0;


        List<String> updateFieldList = ParameterUtils.getScpMatrUpdateFields();
        Boolean hasChange = false;
        String changeFieldTmp = "";

        String remarkAdd = StrUtil.format(
                "305同步耗材后新增，时间:{}",
                DateUtils.format(DateUtils.nowDate(DateUtils.YYYYMMDDHHMMSS_PATTER2),DateUtils.YYYYMMDDHHMMSS_PATTER2)
        );
        for (MatrDTO dto : dtos) {
            Supplier supplier = supplierMap.get(dto.getSupplierMscmCode());
            if (supplier == null) {
                continue;
            }

            Matr matr = matrMap.get(dto.getCode());
            if (matr == null) {
                matr = new Matr();
            }
            if (dto.getName().indexOf("低值耗材2571001") != -1) {
                log.debug("低值耗材2571001");
            }


            // 只有新增的商品才直接设置价格
            if (matr.isNewRecord()) {
                matr.setSkuPrice(dto.getSkuPrice());
                matr.setSupplierId(supplier.getId())
                        .setSupplierName(supplier.getName())
                        .setName(StringUtils.isBlank(dto.getMaterialTradeName()) ? dto.getName() : dto.getMaterialTradeName())
                        .setNamePy(StringUtils.isNotBlank(dto.getNamePy()) ? StringUtils.substring(dto.getNamePy(), 0, 10) : StringUtils.substring(PinYinUtils.getAlpha(dto.getName()), 0, 10))
                        .setSpec(StringUtils.defaultIfBlank(dto.getSpec(), "默认品规"))
                        .setMfgName(dto.getMfgName())
                        .setMfgId("0")
                        .setMscmDisabled(!dto.getInactive())
                        .setFlagHigh(false)
                        .setFlagConsignment(StringUtils.toBoolean(dto.getIsConsignment(), false))
                        .setFlagOmoc(StringUtils.toBoolean(dto.getIsOmoc(), false))
                        .setSkuUnit(dto.getSkuUnit()).setSnCount(1)
                        .setHrpCode(dto.getMaterialHrpCode())
                        .setHrpName(dto.getName())
                        .setMscmCode(dto.getCode());

                // 注册证信息
                matr.setCertificateNo(dto.getCertificateNo()).setCertificateBegin(dto.getCertificateExpiredStartDate()).setCertificateExp(dto.getCertificateExpiredDate());
                matr.setBidno(dto.getBidno());

                // 医保信息
                matr.setHisMedicareNo(dto.getHisMedicareNo()).setHisMedicareName(dto.getHisMedicareName()).setHisMedicareNo2(dto.getHisMedicareNo2()).setHisMedicareName2(dto.getHisMedicareName2());

                // HRP信息
                matr.setId(IdWorker.getIdStr());
                matr.setHrpCode(matr.getId());
                matr.setHrpName(matr.getName());
                matr.setHrpMfg(matr.getMfgName());
                matr.setHrpSpec(matr.getSpec());
                matr.setHrpUnit(matr.getSkuUnit());
                matr.setRemark(remarkAdd);

                saveOrUpdateMatrs.add(matr);
                numAdd++;
                continue;
            }


            if (updateFieldList == null || updateFieldList.size() == 0) {
                continue;
            }

            // 已存在的商品更新部分属性
            hasChange = false;
            changeFieldTmp = "";
            // 规格 spec厂商 mfgName,
            // 注册证号 certificateNo,注册证开始 certificateBegin,注册证截止 certificateExp,
            // 医保代码20位 hisMedicareNo,医保名称20位 hisMedicareName,医保代码27位 hisMedicareNo2,医保名称27位
            if (
                    updateFieldList.contains("spec")
                    && !StringUtils.equalsNoSpec(matr.getSpec(), dto.getSpec())
                    && StringUtils.isNotBlank(dto.getSpec())
            ) {
                matr.setSpec(dto.getSpec());
                matr.setHrpSpec(matr.getSpec());
                hasChange = true;
                changeFieldTmp+=",spec";
            }
            if (
                    updateFieldList.contains("mfgName")
                    && !StringUtils.equalsNoSpec(matr.getMfgName(), dto.getMfgName())
                    && StringUtils.isNotBlank(dto.getMfgName())
            ) {
                matr.setMfgName(dto.getMfgName());
                matr.setHrpMfg(matr.getMfgName());
                hasChange = true;
                changeFieldTmp+=",mfgName";
            }
            if (
                    updateFieldList.contains("certificateNo")
                    && !StringUtils.equalsNoSpec(matr.getCertificateNo(), dto.getCertificateNo())
                    && StringUtils.isNotBlank(dto.getCertificateNo())
            ) {
                matr.setCertificateNo(dto.getCertificateNo());
                hasChange = true;
                changeFieldTmp+=",certificateNo";
            }
            if (
                    updateFieldList.contains("certificateBegin")
                    && !ObjectUtil.equal(matr.getCertificateBegin(), dto.getCertificateExpiredStartDate())
                    && ObjectUtil.isNotNull(dto.getCertificateExpiredStartDate())
            ) {
                matr.setCertificateBegin(dto.getCertificateExpiredStartDate());
                hasChange = true;
                changeFieldTmp+=",certificateBegin";
            }
            if (
                    updateFieldList.contains("certificateExp")
                    && !ObjectUtil.equal(matr.getCertificateExp(), dto.getCertificateExpiredDate())
                    && ObjectUtil.isNotNull(dto.getCertificateExpiredDate())
            ) {
                matr.setCertificateExp(dto.getCertificateExpiredDate());
                hasChange = true;
                changeFieldTmp+=",certificateExp";
            }
            if (
                    updateFieldList.contains("hisMedicareNo")
                    && !StringUtils.equalsNoSpec(matr.getHisMedicareNo(), dto.getHisMedicareNo())
                    && StringUtils.isNotBlank(dto.getHisMedicareNo())
            ) {
                matr.setHisMedicareNo(dto.getHisMedicareNo());
                hasChange = true;
                changeFieldTmp+=",hisMedicareNo";
            }
            if (
                    updateFieldList.contains("hisMedicareName")
                    && !StringUtils.equalsNoSpec(matr.getHisMedicareName(), dto.getHisMedicareName())
                    && StringUtils.isNotBlank(dto.getHisMedicareName())
            ) {
                matr.setHisMedicareName(dto.getHisMedicareName());
                hasChange = true;
                changeFieldTmp+=",hisMedicareName";
            }
            if (
                    updateFieldList.contains("hisMedicareNo2")
                    && !StringUtils.equalsNoSpec(matr.getHisMedicareNo2(), dto.getHisMedicareNo2())
                    && StringUtils.isNotBlank(dto.getHisMedicareNo2())
            ) {
                matr.setHisMedicareNo2(dto.getHisMedicareNo2());
                hasChange = true;
                changeFieldTmp+=",hisMedicareNo2";
            }
            if (
                    updateFieldList.contains("hisMedicareName2")
                    && !StringUtils.equalsNoSpec(matr.getHisMedicareName2(), dto.getHisMedicareName2())
                    && StringUtils.isNotBlank(dto.getHisMedicareName2())
            ) {
                matr.setHisMedicareName2(dto.getHisMedicareName2());
                hasChange = true;
                changeFieldTmp+=",hisMedicareName2";
            }
            if (
                    updateFieldList.contains("bidno")
                    && !StringUtils.equalsNoSpec(matr.getBidno(), dto.getBidno())
                    && StringUtils.isNotBlank(dto.getBidno())
            ) {
                matr.setBidno(dto.getBidno());
                hasChange = true;
                changeFieldTmp+=",bidno";
            }
            if (hasChange) {
                saveOrUpdateMatrs.add(matr);
                numUpdate++;
                if (dto.getName().indexOf("低值耗材2571001") != -1) {
                    log.debug("changeFieldTmp {}", changeFieldTmp);
                }
            }

            // 已存在的商品价格变化
//            if (!NumberUtil.equals(UtilNum.getDouble(dto.getSkuPrice()),UtilNum.getDouble(matr.getSkuPrice()))) {
//                adjustBuild = new AdjustBuildScpDTO();
//                adjustBuild.setSkuPriceBefore(matr.getSkuPrice());
//                adjustBuild.setSkuPriceAfter(dto.getSkuPrice());
//                adjustBuild.setMatrId(matr.getId());
//                adjustBuildList.add(adjustBuild);
//            }

//            if (!hasChange(matr,dto,supplier)) {
//                continue;
//            }
//            matr.setSupplierId(supplier.getId())
//                    .setSupplierName(supplier.getName())
//                    .setName(StringUtils.isBlank(dto.getMaterialTradeName()) ? dto.getName() : dto.getMaterialTradeName())
//                    .setNamePy(StringUtils.isNotBlank(dto.getNamePy()) ? StringUtils.substring(dto.getNamePy(), 0, 10) : StringUtils.substring(PinYinUtils.getAlpha(dto.getName()), 0, 10))
//                    .setSpec(StringUtils.defaultIfBlank(dto.getSpec(), "默认品规"))
//                    .setMfgName(dto.getMfgName())
//                    .setMfgId("0")
//                    .setMscmDisabled(!dto.getInactive())
//                    .setFlagConsignment(StringUtils.toBoolean(dto.getIsConsignment(), false))
//                    .setFlagOmoc(StringUtils.toBoolean(dto.getIsOmoc(), false))
//                    .setSkuUnit(dto.getSkuUnit()).setSnCount(1)
//                    .setCertificateNo(dto.getCertificateNo())
//                    .setHrpCode(dto.getMaterialHrpCode())
//                    .setHrpName(dto.getName())
//                    .setMscmCode(dto.getCode());
//            saveOrUpdateMatrs.add(matr);
//            numUpdate++;
        }

        List<MatrUnit> insertUnits = Lists.newArrayList();
        List<MatrUnit> matrUnits = matrUnitMapper.selectList(new QueryWrapper<MatrUnit>());

        int unitAdd = 0 ,unitUpdate = 0;
        if (!saveOrUpdateMatrs.isEmpty()) {
            // 依据耗材的厂商信息，同步SPD内部厂商数据
            List<Mfg> mfgs = mfgMapper.selectList(Wrappers.query());
            Map<String, Mfg> mfgMap = mfgs.stream().collect(Collectors.toMap(o -> o.getName(), o -> o, (o1, o2) -> o1));

            List<Mfg> insertMfgs = Lists.newArrayList();
            for (Matr matr : saveOrUpdateMatrs) {
                String mfgName = matr.getMfgName();
                if (mfgMap.containsKey(mfgName)) {
                    continue;
                }
                Mfg mfg = new Mfg();
                mfg.setName(mfgName).setFlagActive(true);
                insertMfgs.add(mfg);
                mfgMap.put(mfgName, mfg);
            }
            if (!insertMfgs.isEmpty()) {
                this.saveBatch(Mfg.class, insertMfgs, 1000);
            }


            for (Matr matr : saveOrUpdateMatrs) {
                String mfgName = matr.getMfgName();
                Mfg mfg = mfgMap.get(mfgName);
                matr.setMfgId(mfg == null ? "0" : mfg.getId());
            }

            this.saveOrUpdateBatch(saveOrUpdateMatrs, 1000);
            // 新增默认单位
            Map<String, MatrUnit> matrUnitMapBase = matrUnits.stream().filter(find -> find.getFlagBase()).collect(Collectors.toMap(o -> o.getMatrId(), o -> o, (o1, o2) -> o1));

            // 新增单品单品
            for (Matr matr : saveOrUpdateMatrs) {
                // 单品单位
                if (!matrUnitMapBase.containsKey(matr.getId())) {
                    MatrUnit unit = new MatrUnit();
                    unit.setMatrId(matr.getId()).setUnit(matr.getSkuUnit())
                            .setPrice(matr.getSkuPrice()).setRate(1.0)
                            .setFlagBase(true).setFlagPurchase(true).setFlagApply(true);
                    insertUnits.add(unit);
                    unitAdd++;
                }
            }
        }

        // 新增订单单位

        matrUnits = matrUnitMapper.selectList(new QueryWrapper<MatrUnit>());
        Map<String, MatrDTO> matrDtoByMscmCode = dtos.stream().collect(Collectors.toMap(o -> o.getCode(), o -> o, (o1, o2) -> o1));
        MatrUnit unit;
        for (Matr matr : saveOrUpdateMatrs) {
            if ("商品7705".equals(matr.getName())) {
                log.debug("商品7705调试");
            }

            MatrDTO matrDtoFind = matrDtoByMscmCode.get(matr.getMscmCode());
            if (matrDtoFind == null || StringUtils.isAllBlank(matrDtoFind.getSkuUnit(),matrDtoFind.getOrderUnit())) {
                continue;
            }
            // 订单单位
            if (
                    !matrDtoFind.getSkuUnit().equals(matrDtoFind.getOrderUnit())
            ) {
                Optional<MatrUnit> unitFind =  matrUnits.stream().filter(find -> find.getMatrId().equals(matr.getId())  && find.getUnit().equals(matrDtoFind.getOrderUnit())).
                        findFirst();
                if (unitFind.isPresent()) {
                    unit = unitFind.get();
                    if (
                      NumberUtil.equals(unit.getRate(),matrDtoFind.getOrderUnitRate())
                    ) {
                       continue;
                    }
                    unitUpdate++;
                } else{
                    unitAdd++;
                    unit = new MatrUnit();
                    unit.setMatrId(matr.getId()).setUnit(matrDtoFind.getOrderUnit())
                            .setFlagBase(false).setFlagPurchase(true).setFlagApply(true);
                }
                unit.setPrice(matr.getSkuPrice() * matrDtoFind.getOrderUnitRate()).setRate(matrDtoFind.getOrderUnitRate());
                insertUnits.add(unit);
            }
        }

        if (!insertUnits.isEmpty()) {
            matrUnitService.saveOrUpdateBatch(insertUnits, 1000);
        }

        systemCommonService.buildMatrHisInfo();


        // 调价单
//        String msgAdj = "";
//        if (ObjectUtil.length(adjustBuildList) > 0) {
//            msgAdj = adjustmentService.buildBySpChange(adjustBuildList, "供应商系统商品同步后创建", false);
//            if (StringUtils.isNotBlank(msgAdj)){
//                msgAdj ="," + msgAdj;
//            }
//        }


        String msgAll = StrUtil.format("供应商系统同步耗材,总数量{},新增耗材{},更新耗材{},新增单位{},更新单位{}",
                dtos.size(),
                numAdd,
                numUpdate,
                unitAdd,
                unitUpdate
        );
        if (updateFieldList == null || updateFieldList.size() == 0) {
            msgAll = StrUtil.format("供应商系统同步耗材,总数量{},新增耗材{},新增单位{},更新单位{},参数[scp_matr_update_fields]未指定更新字段，已忽略更新",
                    dtos.size(),
                    numAdd,
                    numUpdate,
                    unitAdd,
                    unitUpdate
            );
        }
        log.info(msgAll);
        return StrUtil.format(msgAll);
    }


    @Override
    public List<Matr> getDeliverItemMatr(List<DeliveryDTO.DeliveryItemDTO> items) {
        if (CollectionUtils.isNotEmpty(items)) {
            List matrCodes = new ArrayList<String>();
            for (DeliveryDTO.DeliveryItemDTO deliveryItem : items) {
                matrCodes.add(deliveryItem.getMaterialCode());
            }
            Wrapper wrapper = Wrappers.<Matr>query().in("mscm_code", matrCodes);
            return baseMapper.selectList(wrapper);
        }
        return new ArrayList<>();
    }

    @Override
    public List<Map> listWithDemand(QueryContext queryContext) {
        int limitCount = limitMatrMapper.selectCount(new QueryWrapper<LimitMatr>()
                .eq("dept_id", queryContext.getParams().get("deptId"))
                .eq("is_demand", GlobalConsts.YES));
        return this.baseMapper.listWithDemand(queryContext.getWrapper(), queryContext.getParams(), limitCount);
    }

    @Override
    public Map uploadPicture(MultipartFile file, String matrId) {
        String matrSavePath = resPath + Const.MATR_IMAGE_SUBPATH;
        String matrThumbnailSavePath = resPath + Const.MATR_IMAGE_THUMBNAIL_SUBPATH;
        String fileName = matrId + "." + getFileType(file.getOriginalFilename());
        try {
            File dir = new File(matrSavePath);
            if (!dir.exists()) { // 判断目录是否存在
                dir.mkdirs();  //多层目录需要调用mkdirs
            }
            BufferedOutputStream out = new BufferedOutputStream(
                    new FileOutputStream(new File(matrSavePath + fileName)));
            out.write(file.getBytes());
            out.flush();
            out.close();
            ImageUtils.resize(matrSavePath + fileName, matrThumbnailSavePath + fileName,
                    Const.MATR_IMAGE_THUMBNAIL_WIDTH, 0, 0, 0);
        } catch (Exception ex) {
            throw new BusinessException(ex.getMessage());
        }
        // 返回原图，缩略图的链接
        String vPath = Const.MATR_IMAGE_VPATH + fileName;
        String vPathThumbnail = Const.MATR_IMAGE_THUMBNAIL_VPATH + fileName;
        this.update(Wrappers.<Matr>update()
                .set("image_url", vPath)
                .set("thumbnail_image_url", vPathThumbnail)
                .eq("id", matrId));
        Map map = new HashMap<String, String>();
        map.put("url", vPath);
        map.put("thumbnailUrl", vPathThumbnail);
        return map;
    }

    private String getFileType(String fileName) {
        Integer start = fileName.lastIndexOf(".");
        if (start > -1) {
            return fileName.substring(start + 1);
        } else {
            return "";
        }
    }

    @Override
    public Page<Map> pageWithStock(QueryContext context, Map<String, Object> userParam) {
        return this.baseMapper.pageWithStock(context.getPage(), context.getWrapper(), context.getParams(), userParam);
    }


    public String getMatrByMscmCode(String mscmCode) {
        String matrId = this.list(Wrappers.<Matr>query().eq("mscm_code", mscmCode)).get(0).id;
        return matrId;
    }

    // 推送商品到供应商系统，定时任务调用
    @Override
    public String matrToMscm() {
        final int limit = 50;
        String infoRet = "";
        int sum = 0;
        Date beginDate = null;
        // 取上次任务执行时间
        Log logDb = Log.getLog(BusType.HisType.type21, LogType.success, "system", "");
        try {
            String strBeginDate  = scheduleJobService.getLastSuccessDate("matrServiceImpl.matrToMscm()");
            beginDate = DateUtils.parse(strBeginDate);
            List<MatrToMscmDTO> matrToMscmDTOS = baseMapper.getMatrToMscm(beginDate);
          if (matrToMscmDTOS.isEmpty()) {
                log.info("本次推送耗材:{}个", sum);
                infoRet = "本次推送耗材:0个";
                logDb.setMsg(infoRet);
                return infoRet;
            }
            log.info("本次推送耗材:{}个", matrToMscmDTOS.size());

            List<Matr> needUpdateMatrList = Lists.newArrayListWithCapacity(limit);
            for (int i = 0; i < matrToMscmDTOS.size(); i += limit) {
                needUpdateMatrList.clear();
                List<MatrToMscmDTO> matrToMscmDTOList = matrToMscmDTOS.stream().skip(i).limit(limit).collect(Collectors.toList());
                ResponseEntity<RestResult> response = mscmService.matrToMscm(strBeginDate, matrToMscmDTOList);

                List<String> codeList = (List<String>) response.getBody().getData();
                if (matrToMscmDTOList == null || matrToMscmDTOList.size() == 0 || codeList == null || codeList.size() != matrToMscmDTOList.size()) {
                    throw new BusinessException("推送耗材返回数据不正确，应返回：" + matrToMscmDTOList.size() + "条数据，现只返回"
                            + codeList.size() + "条，返回报文如下：" + response);
                }
                for (int j = 0; j < matrToMscmDTOList.size(); j++) {
                    if (StringUtils.isBlank(matrToMscmDTOS.get(j).getMaterialCode()) || !codeList.get(j).equalsIgnoreCase(matrToMscmDTOList.get(j).getMaterialCode())) {
                        Matr updateMatr = new Matr();
                        updateMatr.setMscmCode(codeList.get(j)).setId(matrToMscmDTOList.get(j).getMaterialId());
                        needUpdateMatrList.add(updateMatr);
                        sum += 1;
                    }
                }
                if (needUpdateMatrList.size() > 0) {
                    this.saveOrUpdateBatch(needUpdateMatrList);
                }
            }
            log.info("MatrServiceImpl.matrToMscm.本次推送耗材维护耗材编码为: {}个", sum);
            infoRet = "本次推送耗材:" + sum + "个";
            logDb.setMsg(infoRet);
        } catch (Exception e) {
            log.error("MatrServiceImpl.matrToMscm.error", e);
            infoRet = "推送失败，原因：" + e.getMessage();
            logDb.setLog(LogType.error, e.getMessage());
        } finally {
            logService.save(logDb);
            //推送消息给运营管理员 和管理员
            CommonService.pushMessageRole("推送耗材结束【matrServiceImpl.matrToMscm】", logDb.getMsg(), "admin_yy,admin");
        }
        return infoRet;
    }

    public RestResult matrOnceToMscm(List<String> idList) {
        String infoRet = "";
        int sum = 0;
        String beginDate = null;
        RestResult result = RestResult.ok("操作成功");

        try {

            List<MatrToMscmDTO> matrToMscmDTOS = baseMapper.getOnceMatrToMscm(idList);
            if (matrToMscmDTOS.isEmpty()) {
                log.info("本次推送耗材:{}个", matrToMscmDTOS.size());
                infoRet = "本次推送耗材:0个";
                result.setMsg(infoRet);
                result.setCode(ErrorCode.COMMON_ERROR);
                return result;
            }
            BusinessException.throwErrorIf(
                    matrToMscmDTOS.size() == 1 && matrToMscmDTOS.stream().filter(tmp -> StringUtils.isBlank(tmp.getSupplierId())).findFirst().isPresent(),
                    "供应商尚未推送，请先推送供应商"
            );
            log.info("本次推送耗材:{}个", matrToMscmDTOS.size());


            ResponseEntity<RestResult> response = mscmService.matrToMscm(beginDate, matrToMscmDTOS);

            List<String> codeList = (List<String>) response.getBody().getData();

            if (matrToMscmDTOS.isEmpty() || codeList == null ||
                    codeList.size() != matrToMscmDTOS.size()) {
                result.setMsg("推送耗材返回数据不正确，应返回：" + matrToMscmDTOS.size() + "条数据，现只返回"
                        + codeList.size() + "条，返回报文如下：" + response);
                result.setCode(ErrorCode.COMMON_ERROR);
                throw new BusinessException("推送耗材返回数据不正确，应返回：" + matrToMscmDTOS.size() + "条数据，现只返回"
                        + codeList.size() + "条，返回报文如下：" + response);

            }
            for (int j = 0; j < matrToMscmDTOS.size(); j++) {
                if (StringUtils.isBlank(matrToMscmDTOS.get(j).getMaterialCode()) || !codeList.get(j).toLowerCase().equals(matrToMscmDTOS.get(j).getMaterialCode().toLowerCase())) {
                    int num = baseMapper.update(null, Wrappers.<Matr>update().set("mscm_code", codeList.get(j))
                            .eq("id", matrToMscmDTOS.get(j).getMaterialId()));
                    sum++;
                }
            }
            sum = 0;
            if (codeList != null && codeList.size() > 0) {
                sum = codeList.size();
            }
            log.info("本次推送耗材维护耗材编码为: {}个", sum);
            infoRet = "本次推送耗材维护耗材编码为:" + sum + "个";
            result.setMsg(infoRet);
        } catch (Exception e) {
            e.printStackTrace();
            infoRet = "推送失败，原因：" + e.getMessage();
            result.setMsg(infoRet);
            result.setCode(ErrorCode.COMMON_ERROR);
        }
        return result;
    }

    @Override
    public IPage pageUsing(QueryContext context) {
        return this.baseMapper.pageUsing(context.getPage(), context.getWrapper(), context.getParams());

    }

    @Override
    public RestResult copyMatr(String id) {
        RestResult result = RestResult.ok("操作成功");
        Matr matr = this.getById(id);
        List<MatrUnit> matrs = matrUnitMapper.selectList(Wrappers.<MatrUnit>query().eq("matr_id", matr.getId()));
        matr.setId(null);
        matr.setMscmCode(null);
        matr.setRemark(null).setSpec("无").setHrpSpec("无");
        /**
         matr.setHrpMfg(null).setHrpMfgCode(null)
         .setHrpUnit(null).setHrpName(null).setHrpSpec(null)
         .setHisCode(null).setHisPrice(null).setHisName(null)
         matr.setHrpCode(null).setMscmCode(null).setMscmDisabled(false).setMscmDisabledDesc(null);

         */
        matr.setId(IdWorker.getIdStr());
        matr.setHrpCode(matr.getId());
        matr.setMatrIdSync(null);
        this.insertCascadeById(matr);

        for (MatrUnit matrUnit : matrs) {
            matrUnit.setMatrId(matr.getId()).setId(null);
            matrUnitMapper.insert(matrUnit);
        }
        result.setData(matr);
        return result;
    }


    @Override
    public Page<MatrApplyDemandDTO> pageWithStockForApplyDemand(QueryContext context, Map<String, Object> userParam) {
        return this.baseMapper.pageWithStockForApplyDemand(context.getPage(), context.getWrapper(), context.getParams(), userParam);
    }

    @Override
    public Page pageForReportMatr(QueryContext context, Map<String, Object> userParam) {
        return this.baseMapper.pageForReportMatr(context.getPage(), context.getWrapper(), context.getParams(), userParam);
    }

    @Override
    public List<Map> getMatrWarehouseList() {
        return this.baseMapper.getMatrWarehouseList();
    }


    @Override
    public void updateTemporaryPurchase(List<String> list) {
        this.update(Wrappers.<Matr>update().set("flag_temporary_purchase", 0).in("id", list));
    }

    @Override
    public Page pageInStock(QueryContext context, Map<String, Object> userParam) {
        return this.baseMapper.pageInStock(context.getPage(), context.getWrapper(), context.getParams(), userParam);
    }

    /**
     * 根据传过来的耗材ID列表和对应的业务类型通过后台业务禁用配置及耗材的禁用标志决定该业务的这些耗材能否放行
     * @param idList
     * @param businessType
     * @return
     */
    @Override
    public RestResult matrCanPass(List<String> idList, String businessType) {
        RestResult result = RestResult.ok("操作成功");

        //首先判断耗材是否被禁用
        List<Matr> disabledList = this.list(Wrappers.<Matr>query().in("id", idList).eq("flag_disabled", 1));
        if (disabledList != null && disabledList.size() > 0) {
            result.setData(disabledList);//把禁用的耗材放进去，谁调用谁解析去使用
            return result;
        }
        //根据businessType业务类型到数据库通用参数表里面查询该业务类型对应的配置是否需要判断，不需要直接放行，需要则走下一步
        Parameter parameter = parameterMapper.selectOne(Wrappers.<Parameter>query().eq("param_key", "matr_forbidden_type" + businessType));
        if (null == parameter || "0".equals(parameter.getValue())) {//不做禁止直接放行 0：不禁用 1：全禁用 -1：仅一物一码耗材禁用
            result.setSuccess(false);
            result.setMsg("不做禁止直接放行");
            return result;
        }
        List<Matr> forbiddenList = null;
        //需要做限行
        if("-1".equals(parameter.getValue().trim())) {//仅一物一码耗材禁用
            forbiddenList = this.list(Wrappers.<Matr>query().in("id", idList).eq("flag_forbidden", 1).eq("flag_omoc",1));//查询当前耗材ID列表下所有禁用的且是一物一码的耗材
        } else if ("1".equals(parameter.getValue().trim())) {//所有禁用的耗材；不区分一物一码
            forbiddenList = this.list(Wrappers.<Matr>query().in("id", idList).eq("flag_forbidden", 1));//查询当前耗材ID列表下所有禁用的耗材；不区分一物一码
        } else if ("-2".equals(parameter.getValue().trim())) {//-2：仅非一物一码耗材禁用
            forbiddenList = this.list(Wrappers.<Matr>query().in("id", idList).eq("flag_forbidden", 1).eq("flag_omoc",0));//查询当前耗材ID列表下所有禁用的且非一物一码的耗材
        }
        if(forbiddenList == null || forbiddenList.size() == 0) {
            result.setSuccess(false);
            result.setMsg("不做禁止直接放行");
            return result;
        }
        result.setData(forbiddenList);//把禁用的耗材放进去，谁调用谁解析去使用
        return result;
    }

    @Override
    public String importData(List<JSONObject> dataList) {
        List<MatrImportDto> dataImport = JSONArray.parseArray(JSON.toJSONString(dataList), MatrImportDto.class);
        log.debug("导入耗材信息");

        return _doImport(dataImport);
    }

    /***
     * 业务实现
     * @param importMatrDTOS
     * @return
     */
    public String _doImport(List<MatrImportDto> importMatrDTOS){
        BusinessException.throwValidFail("已废弃");

        //1 获取及新增厂商
        List<Mfg> mfgs = mfgMapper.selectList(Wrappers.query());
        List<Mfg> insertOrUpdateMfgs = Lists.newArrayList();
        Optional<Mfg> mfgFind;
        Mfg mfgDb;
        List<String> nameCodeList = new ArrayList<>();
        for (MatrImportDto importMatr : importMatrDTOS.stream().filter(tmp -> StringUtils.isNotBlank(tmp.getMfgHrpCode()) || StringUtils.isNotBlank(tmp.getMfgName())).collect(Collectors.toList())) {
            String finalMfgName = UtilCommon.getStr(importMatr.getMfgName(), "");
            String finalMfgCode = UtilCommon.getStr(importMatr.getHrpMfgCode(), "");
            if (StringUtils.isNotBlank(finalMfgCode) && nameCodeList.contains(finalMfgCode)) {
                continue;
            }
            if (StringUtils.isNotBlank(finalMfgName) &&  nameCodeList.contains(finalMfgName)) {
                continue;
            }
            mfgFind = mfgs.stream().filter(tmp -> finalMfgCode.equals(tmp.getHrpCode()) || finalMfgName.equals(tmp.getName())).findFirst();
            if (mfgFind.isPresent()) {
                mfgDb = mfgFind.get();
            } else {
                mfgDb = new Mfg();
            }
            if (StringUtils.isNotBlank(finalMfgName)) {
                mfgDb.setNamePy(StringUtils.substring(PinYinUtils.getAlpha(finalMfgName),0,10));
                mfgDb.setName(finalMfgName);
                mfgDb.setHrpMfg(finalMfgName);
                nameCodeList.add(finalMfgName);
            }
            if (StringUtils.isNotBlank(finalMfgCode)) {
                mfgDb.setHrpCode(finalMfgCode);
                nameCodeList.add(finalMfgCode);
            }
            insertOrUpdateMfgs.add(mfgDb);

        }
        if (!insertOrUpdateMfgs.isEmpty()) {
            mfgService.saveOrUpdateBatch(insertOrUpdateMfgs, 1000);
            mfgs.addAll(insertOrUpdateMfgs);
        }

        //2 获取及新增供应商
        List<Supplier> suppliers = supplierMapper.selectList(
                Wrappers.<Supplier>query().select("id,name,hrp_code")
        );
        nameCodeList.clear();
        Optional<Supplier> supplierFind;
        Supplier supplierDb;
        List<Supplier> insertOrUpdateSuppliers = Lists.newArrayList();
        for (MatrImportDto importMatr : importMatrDTOS.stream().filter(tmp -> StringUtils.isNotBlank(tmp.getSupplierName()) || StringUtils.isNotBlank(tmp.getSupplierHrpCode())).collect(Collectors.toList())) {
            String supplierName = UtilCommon.getStr(importMatr.getSupplierName(),"");
            String supplierHrpCode = UtilCommon.getStr(importMatr.getSupplierHrpCode(),"");
            if (StringUtils.isNotBlank(supplierName) && nameCodeList.contains(supplierName)) {
                continue;
            }
            if (StringUtils.isNotBlank(supplierHrpCode) && nameCodeList.contains(supplierHrpCode)) {
                continue;
            }
            supplierFind = suppliers.stream().filter(tmp -> supplierHrpCode.equals(tmp.getHrpCode()) || supplierName.equals(tmp.getName())).findFirst();
            if (supplierFind.isPresent()) {
                supplierDb = supplierFind.get();
            } else {
                supplierDb = new Supplier();
            }
            if (StringUtils.isNotBlank(supplierName)) {
                supplierDb.setNamePy(StringUtils.substring(PinYinUtils.getAlpha(supplierName),0,10));
                supplierDb.setName(supplierName);
                nameCodeList.add(supplierName);
            }
            if (StringUtils.isNotBlank(supplierHrpCode)) {
                supplierDb.setHrpCode(supplierHrpCode);
                nameCodeList.add(supplierHrpCode);
            }
            insertOrUpdateSuppliers.add(supplierDb);
        }
        if (!insertOrUpdateSuppliers.isEmpty()) {
            supplierService.saveOrUpdateBatch(insertOrUpdateSuppliers, 1000);
            suppliers.addAll(insertOrUpdateSuppliers);
        }

        //3 获取及新增品类
        List<MatrCategory> categories = matrCategoryMapper.selectList(Wrappers.<MatrCategory>query()
                .select("id,category_name"));
        nameCodeList.clear();
        Optional<MatrCategory> matrCategoryFind;
        MatrCategory matrCategoryDb;

        List<MatrCategory> insertOrUpdateMatrCategorys = Lists.newArrayList();
        for (MatrImportDto importMatr : importMatrDTOS.stream().filter(tmp -> StringUtils.isNotBlank(tmp.getCategoryName())).collect(Collectors.toList())) {
            String categoryName = UtilCommon.getStr(importMatr.getCategoryName(),"");
            if (nameCodeList.contains(categoryName)) {
                continue;
            }
            nameCodeList.add(categoryName);
            matrCategoryFind = categories.stream().filter(tmp -> categoryName.equals(tmp.getCategoryName()) ).findFirst();
            if (matrCategoryFind.isPresent()) {
                matrCategoryDb = matrCategoryFind.get();
            } else {
                matrCategoryDb = new MatrCategory();
                matrCategoryDb.setParentId("0").setParentCode("000000").setCode(categoryName);
            }
            if (StringUtils.isNotBlank(categoryName)) {
                matrCategoryDb.setCategoryName(categoryName);
            }
            insertOrUpdateMatrCategorys.add(matrCategoryDb);
        }
        if (!insertOrUpdateMatrCategorys.isEmpty()) {
            matrCategoryService.saveOrUpdateBatch(insertOrUpdateMatrCategorys, 1000);
            matrCategoryService.repairData();
            categories.addAll(insertOrUpdateMatrCategorys);
        }


        //4 耗材新增或者更新
        // 获取商品
        List<Matr> matrs = this.list(Wrappers.<Matr>query());
        Map<String, Matr> matrGroupHrpCode = matrs.stream()
                .filter(o -> StringUtils.isNotBlank(o.getHrpCode()))
                .collect(Collectors.toMap(o -> o.getHrpCode(), o -> o, (o1, o2) -> o1));
        List<Matr> matrUpdateList = Lists.newArrayList(),matrAddList = Lists.newArrayList();
        int insertAdjustmentNum = 0;
        for (MatrImportDto importMatr : importMatrDTOS) {
            // 耗材
            Matr matr = null;
            if (StringUtils.isNotBlank(importMatr.getHrpCode())) {
                matr = matrGroupHrpCode.get(importMatr.getHrpCode());
            }
            if (matr == null) {
                matr = new Matr();
            }
            BeanUtils.copyProperties(importMatr,matr, "id");
            // 供应商信息
            Matr finalMatr = matr;
            supplierFind = suppliers.stream().filter(tmp -> tmp.getName().equals(finalMatr.getSupplierName())).findFirst();
            BusinessException.throwErrorIf(!supplierFind.isPresent(), "未找到供应商%s", finalMatr.getSupplierName());
            supplierDb = supplierFind.get();
            matr.setSupplierName(supplierDb.getName()).setSupplierId(supplierDb.getId());

            // 厂商信息
            mfgDb = new Mfg();
            if (StringUtils.isNotBlank(importMatr.getMfgHrpCode()) || StringUtils.isNotBlank(importMatr.getMfgName())) {
                mfgFind = mfgs.stream().filter(tmp -> StrUtil.equals(tmp.getHrpCode(),importMatr.getMfgHrpCode()) || StrUtil.equals(tmp.getName(),importMatr.getMfgName())).findFirst();
                if (mfgFind.isPresent()) {
                    mfgDb = mfgFind.get();
                }
            }
            matr.setMfgId(mfgDb.getId()).setMfgName(mfgDb.getName()).setHrpMfg(mfgDb.getHrpMfg()).setHrpMfgCode(mfgDb.getHrpCode());

            // 品类信息
            matrCategoryDb = new MatrCategory();
            matrCategoryDb.setId("0");
            matrCategoryDb.setCategoryName("根分类");
            if (StringUtils.isNotBlank(importMatr.getCategoryName())) {
                matrCategoryFind = categories.stream().filter(tmp -> StrUtil.equals(tmp.getCategoryName(),importMatr.getCategoryName())).findFirst();
                if (matrCategoryFind.isPresent()) {
                    matrCategoryDb = matrCategoryFind.get();
                }
            }
            matr.setCategoryName(matrCategoryDb.getCategoryName()).setCategoryId(matrCategoryDb.getId());

            // 更新耗材时，hrp价格发生改变时，生成调价单
            if (!matr.isNewRecord() && matr.getSkuPrice() != null && importMatr.getSkuPrice() != null && !matr.getSkuPrice().equals(importMatr.getSkuPrice())) {
                insertAdjustmentNum++;
                //价格变动的库存列表
                Matr matr1 = this.getById(matr.getId());
                if (matr1 != null) {
                    AdjustStockDTO adjustStockDTO = new AdjustStockDTO();
                    com.scs.application.core.utils.BeanUtils.copyProperties(matr1, adjustStockDTO);
                    adjustStockDTO.setMatrId(matr1.getId()).setMatrName(matr1.getName()).setMatrSpec(matr1.getSpec());
                    matr1.setSkuPrice(importMatr.getSkuPrice());
                    CommonService.priceChange(matr1, adjustStockDTO, "HRP", "价格变更,生成调价单", matr1.getFlagOmoc(), matr1.getFlagOmoc(), GlobalConsts.adjustTypeHrp);
                }
            }

            matr.setNamePy(StringUtils.substring(PinYinUtils.getAlpha(matr.getName()), 0, 30));

            //HIS信息不存在则替换成商品属性
            matr.setHisCode(UtilCommon.getStr(matr.getHisCode(),matr.getMscmCode()));
            matr.setHisPrice(Double.valueOf(UtilCommon.getStr(matr.getHisPrice()+"",matr.getSkuPrice()+"")));
            matr.setHisName(UtilCommon.getStr(matr.getHisName(),matr.getName()));

            //HRP信息不存在则替换成商品属性
            matr.setHrpMfg(UtilCommon.getStr(matr.getHrpMfg(),matr.getMfgName()));
            matr.setHrpName(UtilCommon.getStr(matr.getHrpName(),matr.getName()));
            matr.setHrpCode(UtilCommon.getStr(matr.getHrpCode(),matr.getMscmCode()));
            matr.setHrpSpec(UtilCommon.getStr(matr.getHrpSpec(),matr.getSpec()));
            matr.setHrpUnit(UtilCommon.getStr(matr.getHrpUnit(),matr.getSkuUnit()));

            // 耗材正常新增
            if (matr.isNewRecord()) {
                matrAddList.add(matr);
            }else {  // 耗材更新 更新HRP相关字段   spd禁用不更新
                matrUpdateList.add(matr);
            }
        }
        if (!matrAddList.isEmpty()) {
            this.saveOrUpdateBatch(matrAddList, 1000);
        }
        if (!matrUpdateList.isEmpty()) {
            this.updateBatchById(matrUpdateList, 1000);
        }

        // 新增或者更新基本单位
        List<MatrUnit> matrUnits = matrUnitService.list(new QueryWrapper<MatrUnit>().eq("flag_base", true));
        Map<String, MatrUnit> matrUnitMap = matrUnits.stream().collect(Collectors.toMap(o -> o.getMatrId(), o -> o, (o1, o2) -> o1));

        List<MatrUnit> insertOrUpdateUnits = Lists.newArrayList();
        for (Matr matr : matrUpdateList) {
            boolean containsKey = matrUnitMap.containsKey(matr.getId());
            if (containsKey) {
                MatrUnit matrUnit = matrUnitMap.get(matr.getId());
                matrUnit.setPrice(matr.getSkuPrice());
                insertOrUpdateUnits.add(matrUnit);
            } else {
                MatrUnit unit = new MatrUnit();
                unit.setMatrId(matr.getId()).setUnit(matr.getSkuUnit())
                        .setPrice(matr.getSkuPrice()).setRate(1.0)
                        .setFlagBase(true).setFlagPurchase(true).setFlagApply(true);
                insertOrUpdateUnits.add(unit);
            }
        }
        for (Matr matr : matrAddList) {
            MatrUnit unit = new MatrUnit();
            unit.setMatrId(matr.getId()).setUnit(matr.getSkuUnit())
                    .setPrice(matr.getSkuPrice()).setRate(1.0)
                    .setFlagBase(true).setFlagPurchase(true).setFlagApply(true);
            insertOrUpdateUnits.add(unit);
        }
        if (!insertOrUpdateUnits.isEmpty()) {
            matrUnitService.saveOrUpdateBatch(insertOrUpdateUnits, 1000);
        }

        return StrUtil.format(
                "导入结束,商品新增数量{},商品更新数量{},单位影响数据{},供应商影响数量{},厂商影响数量{},管理分类影响数量{}",
                matrAddList.size(),
                matrUpdateList.size(),
                insertOrUpdateUnits.size(),
                insertOrUpdateSuppliers.size(),
                insertOrUpdateMfgs.size(),
                insertOrUpdateMatrCategorys.size()
        );
    }

    // 拆分商品
    @Override
    @Transactional(rollbackFor = Exception.class)
    public String excelImportForDataSplit(MultipartFile file, Map<String, String> reqData) {
        List<Matr> itemImportList = excelGetDataList(file,reqData, ExcelImportBaseDataConfig.getMatrDataSplit());

        List<String> listMatrName = itemImportList.stream().map(Matr::getName).collect(Collectors.toList());
        List<String> listMatrSpec = itemImportList.stream().map(Matr::getSpec).collect(Collectors.toList());
        String split = "_" +System.currentTimeMillis() + "_";
        List<Matr> matrListFind = this.list(Wrappers.<Matr>query()
                        .in("name", listMatrName)
                        .or()
                        .in("spec", listMatrSpec)
                )
        ;
        BusinessException.throwValidFailIf(matrListFind.isEmpty(), "未找到相关商品");

        Map<String,List<Matr>> matrGroupByNameAndSpec = matrListFind.stream().collect(Collectors.groupingBy( tmp -> tmp.getName() +split + tmp.getSpec()))
        ;

        List<String> listSupplierName = itemImportList.stream().map(Matr::getSupplierName).distinct().collect(Collectors.toList());

        Map<String,Supplier> supplierMapByName = supplierService.list(Wrappers.<Supplier>query().in("name", listSupplierName))
                .stream().collect(Collectors.toMap(Supplier::getName, t-> t))
        ;
        BusinessException.throwValidFailIf(supplierMapByName == null  || supplierMapByName.keySet().isEmpty(), "所指定的供应商供应商列表都未找到");

        List<String> matrIdList = matrListFind.stream().map(Matr::getId).collect(Collectors.toList());
        Map<String,List<MatrUnit>> matrUnitByMatrId = matrUnitMapper.selectList(Wrappers.<MatrUnit>query().in("matr_id", matrIdList))
                .stream().collect(Collectors.groupingBy(MatrUnit::getMatrId))
                ;

        List<Matr> matrListAdd = new ArrayList<>();
        List<MatrUnit> matrUnitListAdd = new ArrayList<>();
        Matr matrNew;
        MatrUnit matrUnitNew;
        String matrIdOld;
        List<String> matrHrpCodeAndSpNameList = new ArrayList<>();
        List<String> matrNameAndSpecAndSpNameList = this.list(Wrappers.<Matr>query().select("name,spec,supplier_name"))
                .stream()
                .map(matr -> matr.getName()+matr.getSpec()+matr.getSupplierName()).collect(Collectors.toList());

        String findKey;
        for(Matr matr : itemImportList) {
            findKey = matr.getName() +split + matr.getSpec();
            if (!matrGroupByNameAndSpec.containsKey(findKey) || !supplierMapByName.containsKey(matr.getSupplierName())) {
                continue;
            }

            matrNew = new Matr();
            BeanUtils.copyProperties(matrGroupByNameAndSpec.get(findKey).get(0), matrNew);
            matrIdOld = matrNew.getId();
            matrNew.setId(IdWorker.getIdStr());
            matrNew.setHrpCode(matrNew.getId());
            matrNew.setMatrIdSync(null);
            matrNew.setSupplierId(supplierMapByName.get(matr.getSupplierName()).getId());
            matrNew.setSupplierName(supplierMapByName.get(matr.getSupplierName()).getName());
            matrNew.setFlagDisabled(false).setHisDisabled(false).setHrpDisabled(false).setMscmDisabled(false).setHrpFinanceDisabled(false);

            // 同一个商品，同一个供应商，只允许添加一次
            if (matrHrpCodeAndSpNameList.contains(matrIdOld + matrNew.getSupplierId())) {
                continue;
            }

            // 同一个商品，同一个供应商，只允许添加一次
            if (matrNameAndSpecAndSpNameList.contains(matrNew.getName()+matrNew.getSpec()+matrNew.getSupplierName())) {
                continue;
            }
            matrHrpCodeAndSpNameList.add(matrIdOld + matrNew.getSupplierId());

            if (matrUnitByMatrId.containsKey(matrIdOld)) {
                for (MatrUnit matrUnit : matrUnitByMatrId.get(matrIdOld)) {
                    matrUnitNew = new MatrUnit();
                    BeanUtils.copyProperties(matrUnit, matrUnitNew);
                    matrUnitNew.setMatrId(matrNew.getId()).setId(null);
                    matrUnitListAdd.add(matrUnitNew);
                }
            }
            if (StringUtils.isNotBlank(matrNew.getRemark())) {
                matrNew.setRemark(StrUtil.format("{},商品拆分导入，时间:{}",matrNew.getRemark(),DateUtils.format(DateUtils.nowDate(DateUtils.YYYYMMDDHHMMSS_PATTER2),DateUtils.YYYYMMDDHHMMSS_PATTER2)));
            } else{
                matrNew.setRemark(StrUtil.format("商品拆分导入，时间:{}",DateUtils.format(DateUtils.nowDate(DateUtils.YYYYMMDDHHMMSS_PATTER2),DateUtils.YYYYMMDDHHMMSS_PATTER2)));
            }

            matrListAdd.add(matrNew);
        }
        this.saveBatch(matrListAdd, 1000);
        matrUnitService.saveBatch(matrUnitListAdd);
        return StrUtil.format("拆分结束，新增商品:{}，新增单位:{}",matrListAdd.size(),matrUnitListAdd.size());
    }

    // 导入商品
    @Override
    @Transactional(rollbackFor = Exception.class)
    public RestResult excelImportForDataImport(MultipartFile file, Map<String, String> reqData) {
        List<Matr> itemImportList = excelGetDataList(file,reqData, ExcelImportBaseDataConfig.getMatrDataImport());

        //2 获取供应商
        List<Supplier> suppliers = supplierMapper.selectList(
                Wrappers.<Supplier>query().select("id,name")
        );
        BusinessException.throwErrorIf(suppliers.isEmpty(), "请先维护供应商");

        Map<String,Supplier> spByName = suppliers.stream().collect(Collectors.toMap(Supplier::getName, t -> t));

        List<String> spNameList = suppliers.stream().map(Supplier::getName).distinct().collect(Collectors.toList());


        //1 获取及新增厂商
        List<Mfg> mfgs = mfgMapper.selectList(Wrappers.query());
        List<Mfg> mfgAddList = Lists.newArrayList();
        Optional<Mfg> mfgFind;
        Mfg mfgDb;
        List<String> nameCodeList = new ArrayList<>();
        for (Matr importMatr : itemImportList) {
            String finalMfgName = UtilCommon.getStr(importMatr.getMfgName(), "");
            mfgFind = mfgs.stream().filter(tmp -> finalMfgName.equals(tmp.getName())).findFirst();
            if (StringUtils.isBlank(finalMfgName) || (!mfgFind.isPresent() && !nameCodeList.contains(finalMfgName))) {
                mfgDb = new Mfg();
                mfgDb.setNamePy(StringUtils.substring(PinYinUtils.getAlpha(finalMfgName),0,10));
                mfgDb.setName(finalMfgName);
                mfgDb.setHrpMfg(finalMfgName);
                mfgAddList.add(mfgDb);
                nameCodeList.add(finalMfgName);
            }

        }
        if (!mfgAddList.isEmpty()) {
            mfgService.saveBatch(mfgAddList, 1000);
            mfgs.addAll(mfgAddList);
        }


        //3 获取及新增品类
        List<MatrCategory> categories = matrCategoryMapper.selectList(Wrappers.<MatrCategory>query()
                .select("id,category_name"));
        nameCodeList.clear();
        Optional<MatrCategory> matrCategoryFind;
        MatrCategory matrCategoryDb;

        List<MatrCategory> matrCatAddList = Lists.newArrayList();
        for (Matr importMatr : itemImportList) {
            String categoryName = UtilCommon.getStr(importMatr.getCategoryName(),"");
            if (StringUtils.isBlank(categoryName) || nameCodeList.contains(categoryName)) {
                continue;
            }
            nameCodeList.add(categoryName);
            matrCategoryFind = categories.stream().filter(tmp -> categoryName.equals(tmp.getCategoryName()) ).findFirst();
            if (!matrCategoryFind.isPresent()) {
                matrCategoryDb = new MatrCategory();
                matrCategoryDb.setCode(serialRuleAdapter.getSerialRuleService().generateCode(SerialKeys.BASE_MATR_CATEGORY_CODE));
                matrCategoryDb.setCategoryName(categoryName).setParentId("0").setParentCode("000000");
                matrCategoryService.save(matrCategoryDb);
                matrCatAddList.add(matrCategoryDb);
            }
        }
        if (!matrCatAddList.isEmpty()) {
            matrCategoryService.repairData();
            categories.addAll(matrCatAddList);
        }

        //4 耗材新增
        Supplier supplierDb;
        List<Matr> matrAddList = new ArrayList<>();
        String tms = DateUtils.format(DateUtils.now(),DateUtils.YYYYMMDDHHMMSS_PATTER_all2);
        String remark = StrUtil.format(
                "商品导入，时间:{},操作人:{},导入时间戳:{}",
                DateUtils.format(DateUtils.nowDate(DateUtils.YYYYMMDDHHMMSS_PATTER2),DateUtils.YYYYMMDDHHMMSS_PATTER2),
                UserUtils.currentUser().getName(),
                tms
        );
        List<Matr> matrListDb = this.list(Wrappers.query());
        if (matrListDb == null) {
            matrListDb = new ArrayList<>();
        }
        List<String> spNameNotExist = new ArrayList<>();
        List<Integer> matrExistIndex = new ArrayList<>();
        int index = 0;

        MatrCategory catDefault = new MatrCategory();
        catDefault.setId("0");
        catDefault.setCategoryName("根分类");

        for (Matr matr : itemImportList) {
            index++;
            supplierDb = spByName.get(matr.getSupplierName());
            if (supplierDb == null) {
                if (!spNameNotExist.contains(matr.getSupplierName())) {
                    spNameNotExist.add(matr.getSupplierName());
                }
                continue;
            }
            matr.setSupplierName(supplierDb.getName()).setSupplierId(supplierDb.getId());

            // 厂商信息
            mfgDb = mfgs.stream().filter(tmp -> StrUtil.equals(tmp.getName(),matr.getMfgName())).findFirst().get();

            matr.setMfgId(mfgDb.getId()).setMfgName(mfgDb.getName()).setHrpMfg(mfgDb.getHrpMfg()).setHrpMfgCode(mfgDb.getHrpCode());

            // 品类信息
            matrCategoryDb = null;
            if (StringUtils.isNotBlank(matr.getCategoryName())) {
                matrCategoryDb =  categories.stream().filter(tmp -> StrUtil.equals(tmp.getCategoryName(),matr.getCategoryName())).findFirst().get();
            }

            if (matrCategoryDb != null) {
                matr.setCategoryName(matrCategoryDb.getCategoryName()).setCategoryId(matrCategoryDb.getId());
            } else{
                matr.setCategoryName(catDefault.getCategoryName()).setCategoryId(catDefault.getId());
            }


            matr.setNamePy(StringUtils.substring(PinYinUtils.getAlpha(matr.getName()), 0, 30));

            //HRP信息不存在则替换成商品属性
            matr.setHrpMfg(UtilCommon.getStr(matr.getHrpMfg(),matr.getMfgName()));
            matr.setHrpName(UtilCommon.getStr(matr.getHrpName(),matr.getName()));
            matr.setId(IdWorker.getIdStr());
            matr.setHrpCode(matr.getId());
            matr.setHrpSpec(matr.getSpec());
            matr.setHrpUnit(matr.getSkuUnit());
            matr.setRemark(remark);
            matr.setFlagDisabled(true);
            matr.setFlagConsignment(true);
            matr.setHisPrice(matr.getSkuPrice());

            if (matr.getFlagHigh()) {
                matr.setFlagOmoc(true);
                matr.setFlagCenterPurchase(false);
            } else{
                matr.setFlagOmoc(false);
                matr.setFlagCenterPurchase(true);
            }


            // 商品名称、供应商名称、商品规格、单品单位、单品单价如果找到匹配的则忽略新增
            if (matrListDb.stream().filter(
                    find ->
                            find.getName().equals(matr.getName())
                            && find.getSupplierName().equals(matr.getSupplierName())
                            && find.getSpec().equals(matr.getSpec())
                    )
                    .findFirst().isPresent()
            ) {
                matrExistIndex.add(index);
                continue;
            }
            // 耗材正常新增
            matrAddList.add(matr);
            matrListDb.add(matr);
        }
        if (!matrAddList.isEmpty()) {
            this.saveBatch(matrAddList, 1000);
        }

        // 新增基本单位
        List<MatrUnit> insertOrUpdateUnits = Lists.newArrayList();
        for (Matr matr : matrAddList) {
            MatrUnit unit = new MatrUnit();
            unit.setMatrId(matr.getId()).setUnit(matr.getSkuUnit())
                    .setPrice(matr.getSkuPrice()).setRate(1.0)
                    .setFlagBase(true).setFlagPurchase(true).setFlagApply(true);
            insertOrUpdateUnits.add(unit);
        }
        if (!insertOrUpdateUnits.isEmpty()) {
            matrUnitService.saveOrUpdateBatch(insertOrUpdateUnits, 1000);
        }

        systemCommonService.buildMatrHisInfo();

        Map<String,Object> data = new HashMap<>();
        data.put("tms",tms);
        data.put("addNum",matrAddList.size());

        return RestResult.ok(
                StrUtil.format(
                        "导入结束,数据总量{},导入时间戳 {} <br>{}{}{}{}{}",
                        itemImportList.size(),
                        tms,
                        StrUtil.format("商品新增数量{}<br>",matrAddList.size()),
                        mfgAddList.size() > 0 ? StrUtil.format("厂商新增数量{}<br>",mfgAddList.size()) : "",
                        matrCatAddList.size() > 0 ? StrUtil.format("管理分类新增数量{}<br>",matrCatAddList.size()) : "",
                        spNameNotExist.size() > 0 ? StrUtil.format("供应商不存在,数量:{},名称:{}<br>",spNameNotExist.size(),StringUtils.join(spNameNotExist,",")) : "",
                        matrExistIndex.size() > 0 ? StrUtil.format("商品已存在无须新增,数量:{},行索引:{}<br>",matrExistIndex.size(),StringUtils.join(matrExistIndex,",")) : ""
                ),
                data
        );
    }


    @Override
    public String copyMatrBySpNameChange(SpChangeNameDTO changeParam, Supplier supplierNew,String remark) {
        List<Matr> matrList = this.list(Wrappers.<Matr>query().eq("supplier_id",changeParam.getIdFrom()));
        if (matrList.isEmpty()) {
            return "没有可新增的商品";
        }

        Map<String,List<MatrUnit>> unitGroupByMatrId = matrUnitMapper.selectList(Wrappers.<MatrUnit>query().in("matr_id", matrList.stream().map(Matr::getId).collect(Collectors.toList())))
                .stream().collect(Collectors.groupingBy(MatrUnit::getMatrId));

        String matrIdOld;
        List<Matr> matrListAdd = new ArrayList<>();
        List<MatrUnit> unitListAdd = new ArrayList<>();
        for(Matr matr: matrList) {
            matrIdOld = matr.getId();
            matr.setId(null);
            matr.setMatrIdSync(null);
            matr.setMscmCode(null);
            matr.setRemark(null);
            matr.setId(IdWorker.getIdStr());
            matr.setHrpCode(matr.getId());
            matr.setSupplierId(supplierNew.getId());
            matr.setSupplierName(supplierNew.getName());
            matr.setRemark(remark);
            matr.setNamePy(PinYinUtils.getAlpha(matr.getName()));
            matrListAdd.add(matr);

            if (unitGroupByMatrId.containsKey(matrIdOld)) {
                for (MatrUnit matrUnit : unitGroupByMatrId.get(matrIdOld)) {
                    matrUnit.setMatrId(matr.getId()).setId(null);
                    unitListAdd.add(matrUnit);
                }
            }
        }

        if (matrListAdd.size() > 0) {
            this.saveBatch(matrListAdd, 1000);
        }

        if (unitListAdd.size() > 0) {
            matrUnitService.saveBatch(unitListAdd, 1000);
        }

        return StrUtil.format("新增商品数量:{}",matrListAdd.size());
    }
}
